Integração R e Python

um caso de amor (e ódio)

Carolina Musso

José Vitor

Pedro Henrique

Rafael Lira

Vítor de Sousa

Tech Stack

Estrutura da apresentação

  • Motivação

  • Introdução à linguagem python

  • Integração R/python

  • Equivalências do da disciplina no python

  • ML com scikit-learn no R

R ou Python?

Uma briga (quase) superada …

Uma briga (quase) superada …

Qual vocês acham que é o R?

Uma briga (quase) superada …

Fonte: DataCamp

Hadley Wickham

Cientista chefe na RStudio (futura Posit)

Não é uma batalha […] use o que te faz feliz!” , 2019

Diferenças, vantagens, desvantagens….

R

  • Usuários: Acadêmicos, estatísticos, biólogos, economistas …

  • Modelos em poucas linhas, possibilidade de escrever de várias formas.

  • Estatística e visualização (ggplot2!)

  • CRAN, GitHub: + pacotes, + fáceis de instalar e mais documentados.

Python

  • Usuários: Cient. computação, Eng. software …

  • Sensível a indentação.

  • ETL/ML workflows e ambientes de produção escaláveis

  • Pacotes/dependências mais “chatinhos”

E porque integrar R/python afinal?

Argumento 1: Uma pode ser melhor que a outra para um determinado problema.

Python melhor:

  • 2012: todos os requisitos.

R veio depois com:

  • Resumindo: O foco é resolver o problema. Leia o post.

E porque integrar R/python afinal?

  • Argumento 1: Uma pode ser melhor que a outra para um determinado problema.

    R melhor:

    RStudio recentemente:

    Shiny for Python

E porque integrar R/python afinal?

Argumento 2: A sua equipe pode ter pessoas de diferentes linguagens.

(ou uma mistura dos dois!)

Exemplos

1) A preparação dessa apresentação

2) Esta apresentação no rstudio::conf(2022)

Diversidade de pensamento

Mais chances de encontrar a melhor solução para um problema de forma mais eficiente. Leia

Basicamente …

Download Python

(Não é tão trivial quanto o R)

  • Mais opções de IDE:
    • Visual Studio Code
    • Pycharm
    • Spyder
    • Jupyter

Opções de download do python

  • ANACONDA
  • Também é possível baixar pelo python.org

Instale no PATH, ou sofra as consequências

Vantagens do ANACONDA

  • Já vem com os principais pacotes para ciência de dados.
    • Pandas
    • Numpy
    • Seaborn
    • Scikit-learn
    • etc.
  • Também vem com o Jupyter.

Jupyter

  • Interface amigável.
  • Funciona no seu navegador padrão.
  • Possibilidade de escrita de textos com Markdown.
  • Execução e visualização da saída do código em cada célula.
  • Vários atalhos para melhorar a produtividade.
  • Ótima ferramenta para exploração.

Python no R

Reticulate:

O pacote da trégua

Scripts do Python no R

  • Execução de scripts do Python interagindo com a sessão do R
  • Tradução entre objetos do R e do Python (como entre data frames do R e do Pandas)

Reticulate

Lista de comandos

ls("package:reticulate")
  [1] "%as%"                               "array_reshape"                     
  [3] "as_iterator"                        "conda_binary"                      
  [5] "conda_clone"                        "conda_create"                      
  [7] "conda_exe"                          "conda_export"                      
  [9] "conda_install"                      "conda_list"                        
 [11] "conda_python"                       "conda_remove"                      
 [13] "conda_update"                       "conda_version"                     
 [15] "configure_environment"              "dict"                              
 [17] "eng_python"                         "import"                            
 [19] "import_builtins"                    "import_from_path"                  
 [21] "import_main"                        "install_miniconda"                 
 [23] "install_python"                     "iter_next"                         
 [25] "iterate"                            "miniconda_path"                    
 [27] "miniconda_uninstall"                "miniconda_update"                  
 [29] "np_array"                           "py"                                
 [31] "py_available"                       "py_bool"                           
 [33] "py_call"                            "py_capture_output"                 
 [35] "py_clear_last_error"                "py_config"                         
 [37] "py_config_error_message"            "py_del_attr"                       
 [39] "py_del_item"                        "py_dict"                           
 [41] "py_discover_config"                 "py_ellipsis"                       
 [43] "py_eval"                            "py_exe"                            
 [45] "py_func"                            "py_function_docs"                  
 [47] "py_function_wrapper"                "py_get_attr"                       
 [49] "py_get_item"                        "py_has_attr"                       
 [51] "py_help"                            "py_help_handler"                   
 [53] "py_id"                              "py_install"                        
 [55] "py_is_null_xptr"                    "py_iterator"                       
 [57] "py_last_error"                      "py_len"                            
 [59] "py_list_attributes"                 "py_list_packages"                  
 [61] "py_load_object"                     "py_main_thread_func"               
 [63] "py_module_available"                "py_none"                           
 [65] "py_numpy_available"                 "py_repr"                           
 [67] "py_run_file"                        "py_run_string"                     
 [69] "py_save_object"                     "py_set_attr"                       
 [71] "py_set_item"                        "py_set_seed"                       
 [73] "py_str"                             "py_suppress_warnings"              
 [75] "py_to_r"                            "py_to_r_wrapper"                   
 [77] "py_unicode"                         "py_validate_xptr"                  
 [79] "py_version"                         "py_versions_windows"               
 [81] "PyClass"                            "r_to_py"                           
 [83] "register_class_filter"              "register_help_topics"              
 [85] "register_module_help_handler"       "register_suppress_warnings_handler"
 [87] "repl_python"                        "source_python"                     
 [89] "tuple"                              "use_condaenv"                      
 [91] "use_miniconda"                      "use_python"                        
 [93] "use_python_version"                 "use_virtualenv"                    
 [95] "virtualenv_create"                  "virtualenv_exists"                 
 [97] "virtualenv_install"                 "virtualenv_list"                   
 [99] "virtualenv_python"                  "virtualenv_remove"                 
[101] "virtualenv_root"                   

Reticulate:

use_virtualenv("venv", required = TRUE)
# py_install("pandas")
# py_install("numpy")
pandas_r <- import("pandas")

repl_python(
  input = "import numpy as np
  array = np.array([[1,2],[3,4],[5.0,6]])
  print(array)
  print(type(array))"
)
>>>  import numpy as np
>>>    array = np.array([[1,2],[3,4],[5.0,6]])
>>>    print(array)
>>>    print(type(array))
array <- py$array
class(array)
[1] "matrix" "array" 
repl_python(
  input = "
  dictionary = {'alpha': 1, 'beta': 2, 'lista': list(range(5))}
  print(dictionary)
  print(type(dictionary))"
)
>>>  
>>>    dictionary = {'alpha': 1, 'beta': 2, 'lista': list(range(5))}
>>>    print(dictionary)
>>>    print(type(dictionary))
# Convertendo dicionário do Python para lista do R
(dictionary <- py$dictionary)
$alpha
[1] 1

$beta
[1] 2

$lista
[1] 0 1 2 3 4
class(dictionary)
[1] "list"

Rpy2:

Códigos do R no Python

Rcpp:

C++ no R

  • C++: Linguagem de médio/alto nível e com alta performance
  • Veloz
  • Eficiente

Pitfalls

Falta de suporte oficial para R

Suporte oficial do Heroku

Conversando com APIs

Falta de escalabilidade

  • Quando o gasto de tempo não vale a pena (curva de aprendizado)

Limitações do sistema

  • Falta de espaço em disco

  • Falta de RAM

  • Falta de Suporte

Machine Learning com scikit-learn no R

Scikit-learn

  • Popular biblioteca de machine learning para Python;

  • Vasto conjunto de algoritmos para processamento de dados e construção de modelos;

  • Consistente, eficiente e de fácil utilização;

  • Excelente documentação, repleta de exemplos e tutoriais.

Ferramentas do scikit-learn

Pré-processamento

  • Seleção, transformação, criação de variáveis;

  • Codificação de dados categorizados nominais e ordinais;

  • Redução de dimensionalidade (PCA, FA etc.);

  • Imputação de dados faltantes;

  • Manipulação de dados em texto.

  • etc.

Modelos

  • Regressão: linear, ridge, LASSO, SVR etc;
  • Classificação: regressão logística, árvore de decisão, SVM, naive Bayes, LDA/QDA etc;
  • Clusterização: K-Means, misturas gaussianas etc;
  • Outros:
    • Estimação de densidades de probabilidade;

    • Decomposição de sinais;

    • Detecção de anomalias;

    • Redes neurais.

Avaliação e seleção de modelos

  • Particionamento dos dados em treino-teste;

  • Métricas gerais de performance;

  • Estimação de hiperparâmetros;

  • Validação cruzada.

Integrando o scikit-learn ao R

Preparação

  • O primeiro passo é carregar o pacote reticulate e indicar onde serão executados os códigos Python; nesse caso, no ambiente virtual “venv”.
library(reticulate)
use_virtualenv("venv", required=TRUE)
  • Caso precise criar esse ambiente virtual, primeiro execute:
use_python("C:/Users/user/anaconda3")
virtualenv_create("venv",
                  packages=c("scikit-learn",
                             "numpy", "pandas"))

Exemplo: classificação de tumores de mama

library(readr)
breast_cancer <- read_csv("./capitulos/scikit-learn/breast_cancer.csv")
head(breast_cancer)
# A tibble: 6 × 31
  `mean radius` mean t…¹ mean …² mean …³ mean …⁴ mean …⁵ mean …⁶ mean …⁷ mean …⁸
          <dbl>    <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1          18.0     10.4   123.    1001   0.118   0.278   0.300   0.147    0.242
2          20.6     17.8   133.    1326   0.0847  0.0786  0.0869  0.0702   0.181
3          19.7     21.2   130     1203   0.110   0.160   0.197   0.128    0.207
4          11.4     20.4    77.6    386.  0.142   0.284   0.241   0.105    0.260
5          20.3     14.3   135.    1297   0.100   0.133   0.198   0.104    0.181
6          12.4     15.7    82.6    477.  0.128   0.17    0.158   0.0809   0.209
# … with 22 more variables: `mean fractal dimension` <dbl>,
#   `radius error` <dbl>, `texture error` <dbl>, `perimeter error` <dbl>,
#   `area error` <dbl>, `smoothness error` <dbl>, `compactness error` <dbl>,
#   `concavity error` <dbl>, `concave points error` <dbl>,
#   `symmetry error` <dbl>, `fractal dimension error` <dbl>,
#   `worst radius` <dbl>, `worst texture` <dbl>, `worst perimeter` <dbl>,
#   `worst area` <dbl>, `worst smoothness` <dbl>, `worst compactness` <dbl>, …
# ℹ Use `colnames()` to see all variable names

Exemplo: classificação de tumores de mama

  • O objetivo é identificar se um tumor é maligno (câncer de mama) ou benigno.

No scikit-learn, para ajustar um modelo é preciso separar covariáveis, representadas pela data frame X, e variável resposta y.

library(dplyr)
X <- select(breast_cancer, -y)
y <- select(breast_cancer, y) # 0 = maligno, 1 = benigno

Divisão em treino e teste

  • No contexto de machine learning, é rotineiro separar uma parte dos dados para testar a capacidade de um modelo, geralmente, 20% das observações. Isso pode ser feito do seguinte modo no sklearn:
model_sel <- import("sklearn.model_selection")

py_set_seed(42)
split <- model_sel$train_test_split(X, y, test_size=0.20)

X_train <- split[[1]]; X_test <- split[[2]]
y_train <- split[[3]]; y_test <- split[[4]]
  • A função py_set_seed fixa a semente dos geradores de números aleatórios do Python para a reprodução de resultados.

O modelo de classificação

  • Um possível modelo consiste na padronização das variáveis, seguida da retenção dos cinco componentes principais de maior variação e sobre eles um Support Vector Machine.
pipe <- import("sklearn.pipeline")
preproc <- import("sklearn.preprocessing")
decomp <- import("sklearn.decomposition")
svm <- import("sklearn.svm")

model <- pipe$make_pipeline(
  preproc$StandardScaler(),         # Padronização
  decomp$PCA(n_components=5L),      # Componentes principais
  svm$LinearSVC(C=8.71, dual=FALSE) # Support Vector Machine
)

  • O pipeline é análogo ao pipe %>% do R:

    • Sequência de transformações, seguida de um modelo;

    • Unifica e simplifica as etapas de pré-processamento, estimação e ajuste de hiperparâmetros, e previsões.

Ajuste do modelo

  • Os hiperparâmetros n_components e C definidos podem ser ajustados utilizando métodos de validação cruzada (Grid Search, Random Search etc.) sobre o pipeline.

  • Com os hiperparâmetros definidos, ajusta-se o modelo aos dados de treino.
model$fit(X_train, y_train)
  • (Vazamento de dados). O pipeline ajuda a reforçar o uso de apenas os dados de treino para o ajuste.

Performance do modelo

  • Agora, a verificação da qualidade das previsões por meio da acurácia no conjunto de teste.
metrics <- import("sklearn.metrics")
y_pred_test <- model$predict(X_test)

metrics$accuracy_score(y_test, y_pred_test)
[1] 0.9824561
  • O scikit-learn dispõe de outras métricas de performance para modelos de classificação, tais como: acurácia balanceada, precisão, recall, F1 etc.

  • Como estamos num ambiente R, podemos usar de forma natural o ggplot2 e fazer uma comparação gráfica entre o que foi observado e as previsões.
test_data <- X_test
test_data["y"] <- y_test
test_data["y_pred"] <- y_pred_test

library(ggplot2)
ggplot(data=test_data, aes(x=y_pred, y=y))+
  geom_jitter()

Materiais

  1. Para mais informações sobre a biblioteca scikit-learn, veja sua página na web e o guia de usuário;

  2. Como Usar Pipelines no Scikit-Learn - João Paulo Nogueira;

  3. Cross Validation - scikit-learn;

  4. GÉRON, Aurélien (2019). Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow;

  5. Translating between tidymodels and scikit-learn - Kelly Bodwin.

Obrigada!!!